/*
 * ChowLiuTree.h
 *
 *  Created on: 10/11/2011
 *      Author: will
 */

#ifndef CHOWLIUTREE_H_
#define CHOWLIUTREE_H_

#include <vector>
#include <list>
#include <map>
#include <string>
#include <cmath>
#include <iostream>
#include <fstream>
#include <algorithm>

using std::vector;
using std::list;
using std::map;
using std::string;
using std::ofstream;
using std::ifstream;
using std::endl;
using std::sort;

class TrainData {

public:

	vector<float> absolutes;
	int num_samples;
	int sample_size;
	bool ** data;

	void make_absolutes();

	TrainData();
	~TrainData();

	/*
	int makeTrainingData(string movie_file, Codebook  * book,
		commonFeatureExtractor &detector);
	*/
	double P(int &a, bool ais);
	double JP(int &a, bool ais, int &b, bool bis); //a & b
	double CP(int &a, bool ais, int &b, bool bis);	// a | b

	int numberofwords();

};

//-------------##CHOW-LIU TREE##---------------//
//used to store probabilities of words occuring as well as probabilites of a word given
//its 'parent word'.

typedef struct clNode {

	int nodeID;
	int parentNodeID;
	float Pq;
	float Pq_p;
	float Pq_np;

} clNode;

typedef struct info {

	float score;
	short word1;
	short word2;

} info;

class ClTree {

private:

	//has to be built recursively due to underlying tree structure
	void recAddToTree(int, int, TrainData & train_data, list<info> &);
	static bool clNodeCompare(const clNode &first, const clNode &second) ;

	static bool sortInfoScores(info &first, info &second);
	double calcMutInfo(TrainData &train_data, int &word1, int &word2);
	void createBaseEdges(list<info> &edges, TrainData &train_data,
		double info_threshold);
	int reduceEdgesToMinSpan(list<info> &edges, double n_nodes);


	//data
	vector<clNode> nodes;

public:

	//constructors
	ClTree();
	~ClTree();

	//make
	//int make(string movie_file, string tree_file, Codebook &book,
	//	commonFeatureExtractor &detector, double info_threshold = 0);

	int make(TrainData* trainData, double info_threshold);

	//save load
	void save(char * location);
	void save(string location);
	bool load(char * location);
	bool load(string location);

	//functions
	int parent(int);
	double P(int, bool);
	double Pqgp(int, bool, bool);
	int size();

};

#endif /* CHOWLIUTREE_H_ */
